package pl.edu.pw.MidEmu.Samples.MidasChat.UI.Components;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.WindowConstants;

import midas.mw.cam.interfaces.Cam;
import midas.mw.interfaces.Mw;
import pl.edu.pw.MidEmu.Base.Components.BaseFrame;
import pl.edu.pw.MidEmu.Samples.MidasChat.Common.Consts;
import pl.edu.pw.MidEmu.Samples.MidasChat.Logic.Receive;
import pl.edu.pw.MidEmu.Samples.MidasChat.UI.Controllers.ChatFrameController;
import pl.edu.pw.MidEmu.Samples.MidasChat.UI.Views.ChatFrameView;
import pl.edu.pw.MidEmu.Sensing.Sensors.ASensor;
import pl.edu.pw.MidEmu.Sensing.Sensors.GenericSensor;
import pl.edu.pw.MidEmu.Sensing.Sensors.HumiditySensor;
import pl.edu.pw.MidEmu.Sensing.Sensors.LuminancySensor;
import pl.edu.pw.MidEmu.Sensing.Sensors.PressureSensor;
import pl.edu.pw.MidEmu.Sensing.Sensors.TemperatureSensor;

/**
 * Class representing chat frame for MIDAS chat application
 * Performs logic associated with chat functionality
 * 
 * @author Mateusz Starodab
 *
 */
public class ChatFrame extends BaseFrame<JFrame, ChatFrameController> implements ChatFrameView
{
	private JButton btnSend;
	private JButton btnSensors;
	private JComboBox cbxOperator;
	private JComboBox cbxValueType;
	private String contextClass;

	private JLabel lblRemoteClassName;

	private JLabel lblValue;

	private Mw midas;
	private String nodeID;

	private Receive receiver;

	private JTextPane tbxMessageText;

	private JTextPane tbxRecievedText;
	private JTextField tbxRemoteClassName;
	private JTextField tbxValue;

	public ChatFrame(String nodeID, String contextClass, Mw middlewareInterface)
	{
		midas = middlewareInterface;
		this.nodeID = nodeID;
		this.contextClass = contextClass;

		ChatFrameController controller = new ChatFrameController(middlewareInterface);
		controller.setView(this);
		setController(controller);
		JFrame frame = new JFrame();
		setComponent(frame);

		getComponent().setTitle(Consts.ChatFrame_Title + " - " + contextClass + " on " + nodeID);
		getComponent().setSize(400, 300);
		getComponent().setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		getComponent().setLocationByPlatform(true);
		getComponent().addWindowListener(getController());

		JSplitPane pane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);

		tbxRecievedText = new JTextPane();
		receiver = new Receive(this.contextClass, this.nodeID, this.midas, tbxRecievedText);

		JScrollPane receiveTextPanel = new JScrollPane(tbxRecievedText);

		pane.add(receiveTextPanel);

		JPanel pnlSouth = new JPanel(new BorderLayout());

		JPanel pnlSouthTop = new JPanel(new BorderLayout());
		JPanel pnlTopBoxes = new JPanel(new FlowLayout(FlowLayout.LEFT));
		pnlTopBoxes.setPreferredSize(new Dimension(600, 54));

		JPanel pnlSouthBottom = new JPanel(new FlowLayout(FlowLayout.RIGHT));

		tbxRemoteClassName = new JTextField(27);
		lblRemoteClassName = new JLabel(Consts.ChatFrame_RemoteClass);
		lblRemoteClassName.setLabelFor(tbxRemoteClassName);
		pnlTopBoxes.add(lblRemoteClassName);
		pnlTopBoxes.add(tbxRemoteClassName);

		tbxValue = new JTextField(11);
		lblValue = new JLabel(Consts.ChatFrame_Value);
		DefaultComboBoxModel model = new DefaultComboBoxModel();
		model.addElement("None");
		model.addElement(new TemperatureSensor());
		model.addElement(new PressureSensor());
		model.addElement(new LuminancySensor());
		model.addElement(new HumiditySensor());
		model.addElement(new GenericSensor());
		cbxValueType = new JComboBox(model);
		DefaultComboBoxModel operatorModel = new DefaultComboBoxModel();
		operatorModel.addElement(Cam.EQUAL_TO);
		operatorModel.addElement(Cam.GRTEATER_THAN);
		operatorModel.addElement(Cam.GRTEATER_THAN_OR_EQUAL_TO);
		operatorModel.addElement(Cam.LESS_THAN);
		operatorModel.addElement(Cam.LESS_THAN_OR_EQUAL_TO);
		cbxOperator = new JComboBox(operatorModel);
		lblValue.setLabelFor(cbxValueType);
		pnlTopBoxes.add(lblValue);
		pnlTopBoxes.add(cbxValueType);
		pnlTopBoxes.add(tbxValue);
		pnlTopBoxes.add(cbxOperator);

		tbxMessageText = new JTextPane();
		JScrollPane messageTextPanel = new JScrollPane(tbxMessageText);

		btnSend = new JButton(Consts.ChatFrame_btnSend);
		btnSend.setName(Consts.ChatFrame_btnSend);
		btnSend.addActionListener(this.getController());
		pnlSouthBottom.add(btnSend);

		btnSensors = new JButton(Consts.ChatFrame_btnSensors);
		btnSensors.setName(Consts.ChatFrame_btnSensors);
		btnSensors.addActionListener(this.getController());
		pnlSouthBottom.add(btnSensors);

		pnlSouthTop.add(messageTextPanel, BorderLayout.CENTER);

		pnlSouth.add(pnlTopBoxes, BorderLayout.NORTH);
		pnlSouth.add(pnlSouthTop, BorderLayout.CENTER);
		pnlSouth.add(pnlSouthBottom, BorderLayout.SOUTH);

		pane.add(pnlSouth);

		pane.setOneTouchExpandable(true);
		pane.setDividerLocation(0.3);
		pane.setResizeWeight(0.5);

		getComponent().setContentPane(pane);

		getComponent().getRootPane().setDefaultButton(btnSend);
	}

	@Override
	/**
	 * Clears message
	 */
	public void clearMessage()
	{
		tbxRemoteClassName.setText("");
		tbxMessageText.setText("");
		tbxValue.setText("");
		cbxValueType.setSelectedIndex(0);
		cbxOperator.setSelectedIndex(0);
	}

	@Override
	/**
	 * Gets class name
	 */
	public String getClassName()
	{
		return tbxRemoteClassName.getText();
	}

	@Override
	/**
	 * Gates Message text
	 */
	public String getMessageText()
	{
		return tbxMessageText.getText();
	}

	@Override
	/**
	 * Gets operator
	 */
	public String getOperator()
	{
		return (String) cbxOperator.getSelectedItem();
	}

	@Override
	/**
	 * Gets value
	 */
	public String getValue()
	{
		return tbxValue.getText();
	}

	@Override
	/**
	 * Gets value type
	 */
	public ASensor getValueType()
	{
		Object obj = cbxValueType.getSelectedItem();
		if (obj instanceof ASensor)
			return (ASensor) obj;
		return null;
	}

	/**
	 * Inits
	 */
	public void init()
	{
		receiver.start();
	}

	@Override
	/**
	 * Reports sending failure
	 */
	public void reportSendingFailure()
	{
		JOptionPane.showMessageDialog(getComponent(), "There was an error while sending message to MIDAS.\nMake sure MIDAS is running and that you have entered correct context address", "Error while sending message", JOptionPane.ERROR_MESSAGE);
	}

	@Override
	/**
	 * Shows sensors
	 */
	public void showSensors(Hashtable<String, String> sensors)
	{
		String output = "";

		Enumeration<String> keys = sensors.keys();
		while (keys.hasMoreElements())
		{
			String key = keys.nextElement();
			String name = sensors.get(key);
			output += key + " :: " + name + "\n";
		}

		JOptionPane.showMessageDialog(getComponent(), output, "Sensors available on this node", JOptionPane.INFORMATION_MESSAGE);
	}

	@Override
	/**
	 * Terminates
	 */
	public void terminate()
	{
		receiver.terminate();
	}

	@Override
	/**
	 * Validates user data
	 */
	public boolean validate()
	{
		if (getClassName().equals(""))
			return false;
		if (getMessageText().equals(""))
			return false;
		return true;
	}
}
